package com.ji.li.reactadminproexampleservice.service.impl;

import com.ji.li.reactadminproexampleservice.entity.jwt.JwtUser;
import com.ji.li.reactadminproexampleservice.entity.user.User;
import com.ji.li.reactadminproexampleservice.service.AuthService;
import com.ji.li.reactadminproexampleservice.service.MapperService;
import com.ji.li.reactadminproexampleservice.utils.type.CurrentUserUtils;
import com.ji.li.reactadminproexampleservice.utils.type.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ji.li
 */
@Service
public class AuthServiceImpl implements AuthService {

    private final JwtUtils jwtUtils;
    private final CurrentUserUtils currentUserUtils;
    private final StringRedisTemplate stringRedisTemplate;
    private final MapperService mapperService;

    @Autowired
    public AuthServiceImpl(JwtUtils jwtUtils, CurrentUserUtils currentUserUtils,
                           StringRedisTemplate stringRedisTemplate, MapperService mapperService) {
        this.jwtUtils = jwtUtils;
        this.currentUserUtils = currentUserUtils;
        this.stringRedisTemplate = stringRedisTemplate;
        this.mapperService = mapperService;
    }

    @Override
    public String createToken(User user, Boolean rememberMe) {
        JwtUser jwtUser = new JwtUser(user);
        if (!jwtUser.isEnabled()) {
            throw new BadCredentialsException("User is forbidden to login");
        }
        List<String> authorities = jwtUser.getAuthorities()
                .stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toList());
        String token = jwtUtils.createToken(user.getUserName(), user.getuId(), authorities, rememberMe);
        stringRedisTemplate.opsForValue().set(jwtUtils.setRedisKey(user.getuId()), token);
        return token;
    }

    @Override
    public void removeToken() {
        stringRedisTemplate.delete(
                jwtUtils.setRedisKey(mapperService.findUserByName(currentUserUtils.getCurrentUser()).getuId()));
    }
}
